package com.abcode.nettyserversocketio.server;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.abcode.nettyserversocketio.server.message.PrivateMsg;
import com.corundumstudio.socketio.AckRequest;
import com.corundumstudio.socketio.SocketIOClient;
import com.corundumstudio.socketio.annotation.OnConnect;
import com.corundumstudio.socketio.annotation.OnDisconnect;
import com.corundumstudio.socketio.annotation.OnEvent;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.*;

/**
 * @ClassNameSocketIOHandler
 * @Description TODO
 * @Author DELL
 * @Date 2022/1/2114:29
 * @Version 1.0
 **/
@Component
public class SocketIOHandler {
    @Resource
    private ClientCache clientCache;

    /**
     * @Author 二哈老头子
     * @Description //TODO 客户端连接的时候触发，前端js触发：socket = io.connect("http://localhost:9092");
     * @Date 12:12 2022/1/20
     * @Param [client]
     * @return void
     **/
    @OnConnect
    public void onConnect(SocketIOClient client){
        String userId = client.getHandshakeData().getSingleUrlParam("userId");
        String sessionId = client.getSessionId().toString();
        clientCache.saveClient(userId, sessionId, client);
        System.out.println("userId: "+userId+"连接建立成功 - "+sessionId+ "---"+ LocalDateTime.now());
    }

    /**
     * @Author 二哈老头子
     * @Description //TODO 客户端关闭连接时触发：前端js触发：socket.disconnect();
     * @Date 12:14 2022/1/20
     * @Param [client]
     * @return void
     **/
    @OnDisconnect
    public void onDisconnect(SocketIOClient client){

        String sessionId = client.getSessionId().toString();
        clientCache.deleteUserCacheBySessionId(sessionId);
        System.out.println("连接关闭成功 - "+sessionId);
    }

    /**
     * @Author 二哈老头子
     * @Description
     *  //TODO 自定义消息事件，客户端js触发:socket.emit('messageevent', {msgContent: msg});时触发该方法
     *  //TODO 前端js的 socket.emit("事件名","参数数据")方法，是触发后端自定义消息事件的时候使用的
     *  //TODO 前端js的 socket.on("事件名",匿名函数(服务器向客户端发送的数据))为监听服务器端的事件
     * @Date 13:51 2022/1/20
     * @Param [client, request, data]
     * @return void
     **/
    @OnEvent("chatevent")
    public void chatEvent(SocketIOClient client, AckRequest ackRequest, MessageInfo message){
        Long userId = 79L;
        SocketIOClient socketIOClient = clientCache.getUserClient(userId);
        if(socketIOClient != null && socketIOClient.isChannelOpen()){
            socketIOClient.sendEvent("chatevent", message);
            System.out.println("chatevent: " + JSONUtil.toJsonStr(message));
        }

    }

    @OnEvent("private-message")
    public void privateMsgEvent(SocketIOClient client, AckRequest ackRequest, PrivateMsg message){
        System.out.println("private-message: "+ JSONUtil.toJsonStr(message));
        Long toUserId = message.getToUserId();
        SocketIOClient toSocket = clientCache.getUserClient(toUserId);
        if(toSocket != null && toSocket.isChannelOpen()){
            toSocket.sendEvent("private-message", message.getFromUserId(), message.getToUserId(), message.getMsgContent(), message.getSendTimeStamp());
            System.out.println("private-message success "+ JSONUtil.toJsonStr(message));
        }

    }

    @OnEvent("set-user-id")
    public void bingUserId(SocketIOClient client, AckRequest ackRequest, String userId){
     /*   HashMap<UUID, SocketIOClient> userClient = clientCache.getUserClient("79");
        Iterator<Map.Entry<UUID, SocketIOClient>> iterator = userClient.entrySet().iterator();
        while(iterator.hasNext()){
            Map.Entry<UUID, SocketIOClient> next = iterator.next();
            next.getValue().sendEvent("chatevent", message);
        }*/
        clientCache.bindUserId(userId, client);
        System.out.println("set-user-id: "+ userId);
    }

    /**
     * 判断指定的用户ID是否在线
     * @param client
     * @param ackRequest
     * @param userId
     */
    @OnEvent("online-message")
    public void onlineMsg(SocketIOClient client, AckRequest ackRequest, String userId){
           boolean onlineFlag = clientCache.checkOnlineStatus(Long.valueOf(userId));

           Long ownUserId = clientCache.getUserIdBySessionId(client.getSessionId().toString());

        if(ownUserId !=null && ownUserId.toString().equals(userId)){
            client.sendEvent("online-message-reply-own", onlineFlag);
        }else{
            client.sendEvent("online-message-reply-" + ownUserId.toString(), onlineFlag);
        }
    }
}
